﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Caching;
using System.Web.SessionState;

namespace Vision.Utilities.ConsoleApp
{
    public static class ConfigurationHelper
    {
        #region Cookie
        public static HttpCookie GetCookie(string name, HttpCookie defaultValue = default(HttpCookie))
        {
            return GetCookie(HttpContext.Current.Request.Cookies, name, defaultValue);
        }

        public static HttpCookie GetCookie(HttpCookieCollection cookieCollection, string name, HttpCookie defaultValue = default(HttpCookie))
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            HttpCookie retVal;

            if (cookieCollection[name] != null)
            {
                retVal = cookieCollection[name];
            }
            else
            {
                retVal = defaultValue;
            }

            return retVal;
        }

        public static void SetCookie(string name, string value, DateTime? expiredDate)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            SetCookie(HttpContext.Current.Response.Cookies, name, value, expiredDate);
        }

        public static void SetCookie(HttpCookieCollection cookieCollection, string name, string value, DateTime? expiredDate, bool httpOnly = true)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            if (cookieCollection != null)
            {
                HttpCookie cookie = new HttpCookie(name, value);
                cookie.HttpOnly = httpOnly;
                if (expiredDate.HasValue)
                {
                    cookie.Expires = expiredDate.Value;
                }
                cookieCollection.Add(cookie);
            }
        }

        #endregion

        #region Session
        public static T GetSession<T>(string name, T defaultValue = default(T))
        {
            return GetSession<T>(HttpContext.Current.Session, name, defaultValue);
        }

        public static T GetSession<T>(HttpSessionState session, string name, T defaultValue = default(T))
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            if (session == null)
                return defaultValue;

            T retVal;

            if (session[name] != null)
            {
                try
                {
                    retVal = ConvertHelper.ChangeType<T>(session[name]);
                }
                catch
                {
                    retVal = defaultValue;
                }
            }
            else
                retVal = defaultValue;

            return retVal;
        }

        public static void AbandonSession()
        {
            if (HttpContext.Current.Session != null)
            {
                HttpContext.Current.Session.Abandon();
            }
        }

        public static void SetSessionTimeout(int timeout)
        {
            if (HttpContext.Current.Session != null)
                HttpContext.Current.Session.Timeout = timeout;
        }

        public static void RemoveSession(string name)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            if (HttpContext.Current.Session != null)
                HttpContext.Current.Session.Remove(name);
        }

        public static void SetSession(string name, object value)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            if (HttpContext.Current.Session != null)
                SetSession(HttpContext.Current.Session, name, value);
        }
              

        public static void SetSession(HttpSessionState session, string name, object value)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            if (session != null)
            {
                session[name] = value;
            }
        }

        #endregion

        #region Cache

        public static T GetCache<T>(string name, T defaultValue = default(T))
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            T retVal;

            if ((System.Web.HttpRuntime.Cache[name] != null))
            {
                try
                {
                    retVal = ConvertHelper.ChangeType<T>(System.Web.HttpRuntime.Cache.Get(name));
                }
                catch
                {
                    retVal = defaultValue;
                }
            }
            else
                retVal = defaultValue;

            return retVal;
        }

        public static object GetCache(string name)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");
             
            return System.Web.HttpRuntime.Cache[name];
        }

        public static void SetCache(string name, object value, double expiry)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            DateTime dt = DateTime.Now.AddMinutes(expiry);

            System.Web.HttpRuntime.Cache.Insert(name, value, null, dt, System.Web.Caching.Cache.NoSlidingExpiration);
        }

        public static void SetCache(string name, object value)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            System.Web.HttpRuntime.Cache.Insert(name, value);
        }

        public static void SetCache(string name, object value, System.Web.Caching.CacheDependency dependencies)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            System.Web.HttpRuntime.Cache.Insert(name, value, dependencies);
        }

        public static void SetCache(string name, object value, System.Web.Caching.CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan sliderExpiration)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            System.Web.HttpRuntime.Cache.Insert(name, value, dependencies, absoluteExpiration, sliderExpiration);
        }

        public static void SetCache(string name, object value, System.Web.Caching.CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan sliderExpiration, CacheItemPriority priority, CacheItemRemovedCallback callback)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            System.Web.HttpRuntime.Cache.Insert(name, value, dependencies, absoluteExpiration, sliderExpiration, priority, callback);
        }

        public static void RemoveCache(string name)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            System.Web.HttpRuntime.Cache.Remove(name);
        }
        #endregion

        #region Web App Setting
        /// <summary>
        /// Get the App Setting in web.config and custom.config. (custom.config will overwrite the web.config)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static T GetWebAppSetting<T>(string name, T defaultValue = default(T))
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");

            T retVal;

            if ((ConfigurationManager.AppSettings[name] != null))
            {
                try
                {
                    retVal = ConvertHelper.ChangeType<T>(ConfigurationManager.AppSettings[name]);
                }
                catch
                {
                    retVal = defaultValue;
                }
            }
            else
                retVal = defaultValue;

            return retVal;
        }
        #endregion
        
    }
}